package com.example.springbootServiceNetwork.demos.web.Service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springbootServiceNetwork.demos.web.Config.JwtInfo;
import com.example.springbootServiceNetwork.demos.web.Config.Result;
import com.example.springbootServiceNetwork.demos.web.Config.ResultEnum;
import com.example.springbootServiceNetwork.demos.web.Dao.DictDao;
import com.example.springbootServiceNetwork.demos.web.Dao.DictItemDao;
import com.example.springbootServiceNetwork.demos.web.Dao.UserDao;
import com.example.springbootServiceNetwork.demos.web.Dao.UserPurviewDao;
import com.example.springbootServiceNetwork.demos.web.Dto.PageDto;
import com.example.springbootServiceNetwork.demos.web.Entity.Dict;
import com.example.springbootServiceNetwork.demos.web.Entity.DictItem;
import com.example.springbootServiceNetwork.demos.web.Entity.User;
import com.example.springbootServiceNetwork.demos.web.Entity.UserPurview;
import com.example.springbootServiceNetwork.demos.web.Service.QRCodeService;
import com.example.springbootServiceNetwork.demos.web.Service.UserService;
import com.example.springbootServiceNetwork.demos.web.WebSocket.WebSocketServer;
import com.example.springbootServiceNetwork.demos.web.base.RedisDao;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

import static com.example.springbootServiceNetwork.demos.web.Tool.JwtUtil.genAccessToken;
import static com.example.springbootServiceNetwork.demos.web.Tool.JwtUtil.parsePayload;
import static com.example.springbootServiceNetwork.demos.web.Tool.UserIdUtil.*;
import static com.example.springbootServiceNetwork.demos.web.Tool.WrapperMethodUtil.bollPurvieTool;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserDao userDao;
    @Resource
    private UserPurviewDao userPurviewDao;
    @Resource
    private RedisDao redisDao;
    @Resource
    private QRCodeService qrCodeService;
    @Resource
    private DictItemDao dictItemDao;
    @Resource
    private DictDao dictDao;



    @Value("${redis.epxtime}")
    private Long epxtime;

    @Resource
    private WebSocketServer webSocketServer;
    /**
     * 用户注册
     */
    @Override
    public Result register(User user){
        Result result =new Result();
        LambdaQueryWrapper<User>lwq =new LambdaQueryWrapper<>();
        lwq.eq(User::getCellPhone,user.getCellPhone());
        List<User> userList =userDao.selectList(lwq);
        if (userList.isEmpty()){
            String userId =generateUserId(user);
            user.setUserId(userId);
            user.setStatus(1);
            user.setCreateTime(new Date());//创建时间
            user.setOnlineStatus("1");
            String token = genAccessToken(user,"ordinary");
            redisDao.vSet(userId, user,epxtime);
            int res =userDao.insert(user);
            if (res==1){
                UserPurview userPurview =new UserPurview();
                userPurview.setUserId(userId);
                userPurview.setUserPurview("ordinary");
                userPurviewDao.insert(userPurview);
                result.setCode(ResultEnum.SUCCESS.getCode());
                result.setMsg(ResultEnum.SUCCESS.getData());
                result.setData(token);
            }else {
                result.setCode(ResultEnum.BADREQUEST.getCode());
                result.setMsg(ResultEnum.BADREQUEST.getData());
            }
        }else {
            result.setCode(ResultEnum.NODATE.getCode());
            result.setMsg("账号重复！");
        }
        return result;
    }

    /**
     * 登录接口
     */
    @Override
    public Result login(User user){
        Result result =new Result();
        LambdaQueryWrapper<User> lwq =new LambdaQueryWrapper<>();
        lwq.eq(User::getCellPhone,user.getCellPhone());
        lwq.eq(User::getPassword,user.getPassword());
        List<User>userList =userDao.selectList(lwq);
        if (userList.isEmpty()){
            result.setCode(ResultEnum.BADREQUEST.getCode());
            result.setMsg("登陆失败！");
        }else {
            UserPurview userPurview=userPurviewDao.selectById(userList.get(0).getUserId());
            String token = genAccessToken(userList.get(0),userPurview.getUserPurview());
            redisDao.vSet(userList.get(0).getUserId(), userList.get(0),epxtime);
            if (Objects.equals(String.valueOf(userList.get(0).getStatus()), "1")){
                result.setCode(ResultEnum.SUCCESS.getCode());
                result.setMsg("登录成功");
                result.setData(token);
            }else {
                Dict dict = dictDao.selectById(20);
                LambdaQueryWrapper<DictItem> lqw =new LambdaQueryWrapper<>();
                lqw.eq(DictItem::getParentId,dict.getId());
                List<DictItem> dictItemList= dictItemDao.selectList(lqw);
                if (!dictItemList.isEmpty()){
                    for(DictItem item:dictItemList){
                        if (Objects.equals(item.getDictCode(), String.valueOf(userList.get(0).getStatus()))){
                            result.setCode(ResultEnum.DB_QUERY_FAILURE.getCode());
                            result.setMsg(item.getDictName());
                        }else {
                            result.setCode(ResultEnum.DB_QUERY_FAILURE.getCode());
                            result.setMsg("账户异常");
                        }
                    }
                }else {
                    result.setCode(ResultEnum.DB_QUERY_FAILURE.getCode());
                    result.setMsg("账户异常");
                }
            }
        }
        return result;
    }

    /**
     * 扫码登录
     */
    @Override
    public Result scanCodeLogin(Object obj){
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(obj));
        Result result =new Result();
        Claims claims =parsePayload((String) jsonObject.get("scInfo"));
        JSONObject jsonObject1 =JSONObject.parseObject(JSON.toJSONString(claims));
        HashMap<String,String>map =new HashMap<>();
        if (!String.valueOf(jsonObject1.get("jti")).isEmpty()){
            User user =userDao.selectById(String.valueOf(jsonObject1.get("jti")));
            UserPurview userPurview=userPurviewDao.selectById(user.getUserId());
            String token = genAccessToken(user,userPurview.getUserPurview());
            redisDao.vSet(user.getUserId(), user,epxtime);
            map.put("userName", user.getUserName());
            map.put("image", user.getImage());
            map.put("token",token);
            //推送数据
            boolean webSocketCode= webSocketServer.sendMessageToUser(String.valueOf(jsonObject.get("uuid")),token);
            if (webSocketCode){
                result.setCode(ResultEnum.SUCCESS.getCode());
                result.setMsg("登录成功");
                result.setData(map);
            }else {
                result.setCode(ResultEnum.DB_UPDATE_FAILURE.getCode());
                result.setMsg("扫码登录失败！");
                result.setData(token);
            }
        }else {
            result.setCode(ResultEnum.AUTHORIZE_FAILURE.getCode());
            result.setMsg(ResultEnum.AUTHORIZE_FAILURE.getData());
        }
        return result;
    }

    /**
     * 查询用户信息
     */
    @Override
    public Result selUserInfo(String userId){
        Result result =new Result();
        User user =userDao.selectById(userId);
        //用户上线
        User user1 = new User();
        user1.setUserId(user.getUserId());
        user1.setOnlineStatus("1");
        userDao.updateById(user1);
        if (!(user ==null)){
            result.setCode(ResultEnum.SUCCESS.getCode());
            result.setMsg("用户信息查询成功");
            result.setData(user);
        }else {
            result.setCode(ResultEnum.DB_QUERY_FAILURE.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
        }
        return result;
    }

    /**
     * 查询贡献者
     */
    @Override
    public Result queryContributors(User user){
        Result result =new Result();
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.select(User::getUserName,User::getImage,User::getOnlineStatus,User::getUserId);
        lqw.eq(User::getContributors,user.getContributors());
        List<User> userList = userDao.selectList(lqw);
        if (!userList.isEmpty()){
            Object objectList = userList;
            result.setCode(ResultEnum.SUCCESS.getCode());
            result.setMsg("贡献值查询成功");
            result.setData(objectList);
        }else {
            result.setCode(ResultEnum.DB_QUERY_FAILURE.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
        }
        return result;
    }

    /**
     * 校验用户登录接口
     */
    @Override
    public Result verifyUser(String userId){
        Result result =new Result();
        User user =userDao.selectById(userId);
        if (!(user ==null)){
            UserPurview userPurview=userPurviewDao.selectById(user.getUserId());
            String token = genAccessToken(user,userPurview.getUserPurview());
            redisDao.vSet(user.getUserId(), user,epxtime);
            result.setCode(ResultEnum.SUCCESS.getCode());
            result.setMsg("用户校验成功");
            result.setData(token);
        }else {
            result.setCode(ResultEnum.DB_QUERY_FAILURE.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
        }
        return result;
    }

    /**
     * 更新用户信息
     */
    @Override
    public Result updateUser(User user, JwtInfo jwtInfo){
        Result result = new Result();
        try {
            if (Objects.equals(jwtInfo.getUserId(), user.getUserId())){
                user.setStatus(null);
                user.setCellPhone(null);
                int res=userDao.updateById(user);
                if (res==1){
                    result.setCode(ResultEnum.SUCCESS.getCode());
                    result.setMsg("更新成功");
                }else {
                    result.setCode(ResultEnum.FAILED_VISA_INSPECTION.getCode());
                    result.setMsg("更新失败");
                }
            }else {
                result.setCode(ResultEnum.SUCCESS.getCode());
                result.setMsg("您暂无权限！");
            }
        }catch (Exception e){
            result.setCode(ResultEnum.UNKNOWNERROR.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
            result.setData(e.getCause());
        }
        return result;
    }

    /**
     * 用户注销账户（删除）
     */
    @Override
    public Result deleteUser(User user, JwtInfo jwtInfo){
        Result result = new Result();
        try {
            if (Objects.equals(jwtInfo.getUserId(), user.getUserId())){
                int res=userDao.deleteById(user);
                if (res==1){
                    userPurviewDao.deleteById(user.getUserId());
                    result.setCode(ResultEnum.SUCCESS.getCode());
                    result.setMsg("删除成功");
                }else {
                    result.setCode(ResultEnum.FAILED_VISA_INSPECTION.getCode());
                    result.setMsg("删除失败");
                }
            }else {
                result.setCode(ResultEnum.SUCCESS.getCode());
                result.setMsg("您暂无权限！");
            }
        }catch (Exception e){
            result.setCode(ResultEnum.UNKNOWNERROR.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
            result.setData(e.getCause());
        }
        return result;

    }

    /**
     * 更新用户在线状态为离线
     */
    @Override
    public Result updateOffline(User user){
        Result result = new Result();
        try {
            userDao.updateById(user);
            result.setCode(ResultEnum.SUCCESS.getCode());
            result.setMsg("在线状态更新成功");
        }catch (Exception e){
            result.setCode(ResultEnum.UNKNOWNERROR.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
            result.setData(e.getCause());
        }
        return result;

    }

    /**
     * 分页查询所有用户信息
     * 后台
     */
    @Override
    public Result queryAllUser(PageDto pageDto, JwtInfo jwtInfo){
        Result result = new Result();
        try {
            if (bollPurvieTool(jwtInfo.getPurview(),"admin" )){
                User user = JSON.parseObject(JSON.toJSONString(pageDto.getParam()),User.class);
                LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
                //用户名
                if (user.getUserName()!=null){
                    lqw.like(User::getUserName,user.getUserName());
                }
                //手机号
                else if (user.getCellPhone()!=null){
                    lqw.like(User::getCellPhone,user.getCellPhone());
                }
                //居住地址
                else if (user.getAddress()!=null){
                    lqw.like(User::getAddress,user.getAddress());
                }
                //年龄
                else if (user.getAge()!=null){
                    lqw.like(User::getAge,user.getAge());
                }
                //身份证
                else if (user.getSdcard()!=null){
                    lqw.like(User::getSdcard,user.getSdcard());
                }
                //邮箱号
                else if (user.getEmail()!=null){
                    lqw.like(User::getEmail,user.getEmail());
                }
                //兴趣爱好
                else if (user.getHobby()!=null){
                    lqw.like(User::getHobby,user.getHobby());
                }
                //状态
                else if (user.getStatus()!=null){
                    lqw.like(User::getStatus,user.getStatus());
                }
                else if (user.getSex()!=null){
                    lqw.like(User::getSex,user.getSex());
                }
                //创建分页
                Page<User> page = new Page<>(pageDto.getPage(),pageDto.getLimit());
                //获取到分页集合
                Page<User> userPage = userDao.selectPage(page, lqw);
                // 返回对象得到分页所有数据
                result.setCount(Math.toIntExact(userDao.selectCount(null)));
                result.setData(userPage.getRecords());
                result.setMsg("用户查询成功");
                result.setCode(ResultEnum.SUCCESS.getCode());
            }else {
                result.setCode(ResultEnum.SUCCESS.getCode());
                result.setMsg("您暂无权限！");
            }
        }catch (Exception e){
            result.setCode(ResultEnum.UNKNOWNERROR.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
            result.setData(e.getCause());
        }
        return result;
    }

    /**
     * 更新用户信息
     * 后台
     */
    @Override
    public Result updateAllUser(User user, JwtInfo jwtInfo){
        Result result = new Result();
        try {
            if (bollPurvieTool(jwtInfo.getPurview(),"admin" )){
                user.setCellPhone(null);
                int res = userDao.updateById(user);
                if (res==1){
                    result.setMsg("更新成功");
                    result.setCode(ResultEnum.SUCCESS.getCode());
                }else {
                    result.setMsg("更新失败");
                    result.setCode(ResultEnum.BADREQUEST.getCode());
                }
            }else {
                result.setCode(ResultEnum.SUCCESS.getCode());
                result.setMsg("您暂无权限！");
            }
        }catch (Exception e){
            result.setCode(ResultEnum.UNKNOWNERROR.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
            result.setData(e.getCause());
        }
        return result;
    }

    /**
     * 删除账户
     * 后台
     */
    @Override
    public Result deleteAllUser(User user, JwtInfo jwtInfo){
        Result result = new Result();
        try {
            if (bollPurvieTool(jwtInfo.getPurview(),"admin" )){
                int res = userDao.deleteById(user);
                if (res==1){
                    userPurviewDao.deleteById(user.getUserId());
                    result.setMsg("删除成功");
                    result.setCode(ResultEnum.SUCCESS.getCode());
                }else {
                    result.setMsg("删除失败");
                    result.setCode(ResultEnum.BADREQUEST.getCode());
                }
            }else {
                result.setCode(ResultEnum.SUCCESS.getCode());
                result.setMsg("您暂无权限！");
            }
        }catch (Exception e){
            result.setCode(ResultEnum.UNKNOWNERROR.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
            result.setData(e.getCause());
        }
        return result;
    }
}
